package com.ruoyi.central.controller;

import com.ruoyi.central.constant.CentralConstants;
import com.ruoyi.central.domain.TopCentralMaterial;
import com.ruoyi.central.domain.TopCentralProduct;
import com.ruoyi.central.domain.TopCentralProductType;
import com.ruoyi.central.enums.MaterialStatusEnum;
import com.ruoyi.central.enums.ProductMaterialType;
import com.ruoyi.central.publisher.PublisherUtils;
import com.ruoyi.central.publisher.event.TopCentralMaterialEvent;
import com.ruoyi.central.service.ITopCentralMaterialService;
import com.ruoyi.central.service.ITopCentralOperationStationService;
import com.ruoyi.central.service.ITopCentralProductService;
import com.ruoyi.central.service.ITopCentralProductTypeService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.StateVo;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SignEnum;
import com.ruoyi.common.enums.common.State;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.EnumUtils;
import com.ruoyi.common.utils.bean.SelectUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.service.ServiceUtils;
import com.ruoyi.common.validation.group.InsertGroup;
import com.ruoyi.common.validation.group.UpdateBatchGroup;
import com.ruoyi.common.validation.group.UpdateGroup;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 物料Controller
 * 
 * @author SunLuQuan
 * @date 2022-04-12
 */
@Controller
@RequestMapping("/central/centralMaterial")
public class TopCentralMaterialController extends BaseController
{
    private String prefix = "central/centralMaterial";

    @Autowired
    private ITopCentralMaterialService topCentralMaterialService;

    @Autowired
    private ITopCentralProductTypeService productTypeService;

    @Autowired
    private ITopCentralProductService productService;

    @Autowired
    private ITopCentralOperationStationService operationStationService;

    @RequiresPermissions("central:centralMaterial:view")
    @GetMapping()
    public String centralMaterial()
    {
        return prefix + "/centralMaterial";
    }

    /**
     * 合成物料页面
     * @return
     */
    @GetMapping("/syntheticMaterial")
    public String syntheticMaterial(){ return prefix + "/syntheticMaterial"; }

    /**
     * 查询物料列表
     */
    @RequiresPermissions("central:centralMaterial:list")
    @GetMapping("/list")
    @ResponseBody
    public TableDataInfo list(TopCentralMaterial topCentralMaterial)
    {
        startPage();
        List<TopCentralMaterial> list = topCentralMaterialService.selectList(topCentralMaterial);
        ServiceUtils.complete(list,productTypeService,(materialTypeMap,material)->{
            material.setMaterialType(materialTypeMap.get(material.getTypeId()));
            material.setParentMaterialType(materialTypeMap.get(material.getParentTypeId()));
        });
        ServiceUtils.complete(list,operationStationService,((operationStationMap, material) -> material.setOperationStation(operationStationMap.get(material.getOperationStationId()))));
        return getDataTable(list);
    }

    /**
     * 查询简单的物料列表 用于select选择器
     */
    @GetMapping("/simpleList")
    @ResponseBody
    public AjaxResult simpleList(TopCentralMaterial topCentralMaterial){

        Collection<TopCentralMaterial> topCentralMaterialList = topCentralMaterialService.selectAllMap().values();

        return AjaxResult.success(SelectUtils.buildSelectList(topCentralMaterialList,TopCentralMaterial::getId,TopCentralMaterial::getBatchNo));
    }

    /**
     * 获取物料详细信息
     */
    @RequiresPermissions("central:centralMaterial:query")
    @GetMapping(value = "/{id}")
    @ResponseBody
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return AjaxResult.success(topCentralMaterialService.selectById(id));
    }

    /**
     * 获取自增排序值
     * @param topCentralMaterial 过滤条件
     * @return
     */
    @GetMapping("/getIncrementWeight")
    @ResponseBody
    public AjaxResult getIncrementWeight(TopCentralMaterial topCentralMaterial){
        int weigth = topCentralMaterialService.getMaxOfWeight(topCentralMaterial);
        return AjaxResult.success(++weigth);
    }

    /**
     * 下载物料导入模板
     */
    @GetMapping("/importTemplate")
    @ResponseBody
    public void importTemplate(HttpServletResponse response)
    {
        ExcelUtil<TopCentralMaterial> util = new ExcelUtil<>(TopCentralMaterial.class);
        util.importTemplateExcel(response, "物料数据");
    }

    /**
     * 导入物料数据
     * @param file 物料数据文件
     * @param updateSupport 是否为更新
     */
    @Log(title = "物料", businessType = BusinessType.IMPORT)
    @RequiresPermissions("central:centralMaterial:import")
    @PostMapping("/importData")
    @ResponseBody
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
    {
        ExcelUtil<TopCentralMaterial> util = new ExcelUtil<>(TopCentralMaterial.class);
        List<TopCentralMaterial> topCentralMaterialList = util.importExcel(file.getInputStream());

        if(updateSupport){
            if(topCentralMaterialService.updateBatchById(topCentralMaterialList)){
                return AjaxResult.success("导入物料数据覆盖成功！");
            }
            return AjaxResult.error("导入物料数据覆盖失败！");
        }
        if(topCentralMaterialService.insertBatch(topCentralMaterialList)){
            return AjaxResult.success("导入物料数据新增成功！");
        }
        return AjaxResult.error("导入物料数据新增失败！");
    }

    /**
     * 导出物料列表
     */
    @RequiresPermissions("central:centralMaterial:export")
    @Log(title = "物料", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(TopCentralMaterial topCentralMaterial)
    {
        List<TopCentralMaterial> list = topCentralMaterialService.selectList(topCentralMaterial);
        ExcelUtil<TopCentralMaterial> util = new ExcelUtil<TopCentralMaterial>(TopCentralMaterial.class);
        return util.exportExcel(list, "物料数据");
    }

    /**
     * 新增物料
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存物料
     */
    @RequiresPermissions("central:centralMaterial:add")
    @Log(title = "物料", businessType = BusinessType.INSERT)
    @PostMapping
    @ResponseBody
    public AjaxResult addSave(@Validated(InsertGroup.class) @RequestBody TopCentralMaterial topCentralMaterial)
    {
        Map<? extends Serializable, TopCentralProductType> materialTypeMap = productTypeService.selectAllMap();

        Integer productTypeId = topCentralMaterial.getProductTypeId();
        topCentralMaterial.setProductType(materialTypeMap.get(productTypeId));

        Integer typeId = topCentralMaterial.getTypeId();
        topCentralMaterial.setMaterialType(materialTypeMap.get(typeId));

        Integer parentTypeId = topCentralMaterial.getParentTypeId();
        topCentralMaterial.setParentMaterialType(materialTypeMap.get(parentTypeId));

        TopCentralProductType productType = topCentralMaterial.getProductType();
        TopCentralProductType materialType = topCentralMaterial.getMaterialType();
        TopCentralProductType parentMaterialType = topCentralMaterial.getParentMaterialType();

        Assert.notNull(productType,"新增物料失败，物料对应的产品类型不存为或不可用！");

        if(!EnumUtils.equals(ProductMaterialType.FINISHED_PRODUCT,productType.getProductMaterialTypeId())){
            return AjaxResult.error(StringUtils.format("新增物料失败，物料对应的产品类型必须为：{}",ProductMaterialType.FINISHED_PRODUCT.getInfo()));
        }

        Assert.notNull(materialType,"新增物料失败，物料对应的类型不存为或不可用！");

        Assert.notNull(parentMaterialType,"新增物料失败，物料对应的父物料类型不存为或不可用！");

        if(!EnumUtils.equals(ProductMaterialType.SEMI_FINISHED_PRODUCT,parentMaterialType.getProductMaterialTypeId())){
            return AjaxResult.error(StringUtils.format("新增物料失败，物料对应的父物料类型必须为：{}",ProductMaterialType.SEMI_FINISHED_PRODUCT.getInfo()));
        }

        topCentralMaterial.setCreateType(CentralConstants.MANUALLY_ENTRY);

        return toAjax(topCentralMaterialService.insert(topCentralMaterial));
    }

    /**
     * 修改物料
     */
    @RequiresPermissions("central:centralMaterial:edit")
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") String id, ModelMap mmap)
    {
        TopCentralMaterial topCentralMaterial = topCentralMaterialService.selectById(id);

        Map<? extends Serializable, TopCentralProductType> topCentralProductTypeMap = productTypeService.selectAllMap();
        Integer typeId = topCentralMaterial.getTypeId();
        topCentralMaterial.setMaterialType(topCentralProductTypeMap.get(typeId));

        TopCentralProduct product = productService.selectUsableByBatchNo(topCentralMaterial.getBatchNo());

        if(StringUtils.isNotNull(product)){
            Integer productTypeId = product.getTypeId();
            topCentralMaterial.setProductTypeId(productTypeId);
            //mmap.put("rootProduct",topCentralProductTypeMap.get(productTypeId));
        }

        mmap.put("topCentralMaterial", topCentralMaterial);

        return prefix + "/edit";
    }

    /**
     * 修改保存物料
     */
    @RequiresPermissions("central:centralMaterial:edit")
    @Log(title = "物料", businessType = BusinessType.UPDATE)
    @PutMapping
    @ResponseBody
    public AjaxResult editSave(@Validated(UpdateGroup.class) @RequestBody TopCentralMaterial topCentralMaterial)
    {
        PublisherUtils.publishEvent(TopCentralMaterialEvent.class,topCentralMaterial,SignEnum.UPDATE);
        return toAjax(topCentralMaterialService.updateById(topCentralMaterial));
    }

    /**
     * 修改物料 状态 根据 ids 主键
     */
    @RequiresPermissions("central:centralMaterial:edit")
    @Log(title = "物料", businessType = BusinessType.UPDATE)
    @PutMapping("/updateStateByIds")
    @ResponseBody
    public AjaxResult updateStateByIds(@Validated(value= UpdateBatchGroup.class)@RequestBody StateVo<String> stateVo)
    {
        State state = stateVo.getState();
        List<TopCentralMaterial> materials = ServiceUtils.toBeanList(stateVo.getIds(), TopCentralMaterial.class, (material, id) -> {
            material.setId(id);
            material.setState(state);
        });
        PublisherUtils.publishEvent(TopCentralMaterialEvent.class,materials,SignEnum.UPDATE);

        return toAjax(topCentralMaterialService.updateStateByIds(stateVo.getIds(),stateVo.getState()));
    }

    /**
     * 删除物料
     */
    @RequiresPermissions("central:centralMaterial:remove")
    @Log(title = "物料", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ResponseBody
    public AjaxResult deleteByIds(@PathVariable("ids") List<String> ids)
    {
            return toAjax(topCentralMaterialService.deleteByIds(ids));
    }
}
